
extern "C" {
    pub fn printstr(p : *const u8, l : u32);
    fn in_port_byte(port : u16) -> u8;
    fn print_char(ch: char);
    fn printint(u: u32);
}

struct ScanCode;
impl ScanCode {
    // 读取扫描码
    pub fn read() -> u8 {
        unsafe { in_port_byte(0x60)}
    }
}

// 按键状态：按下和弹起
#[derive(PartialEq)]
enum KeyState {
    KeyUp,
    KeyDown,
}

pub struct KeyEvent {
    key_state: KeyState,
    key_code: KeyCode,
}

pub trait ScanCodeSet {
    fn to_key(scancode: u8) -> Option<KeyEvent>;
}

#[allow(dead_code)]
#[derive(Clone, Copy)]
enum KeyCode {
    AltLeft, // 左alt
    AltRight,
    ArrowDown, // 箭头
    ArrowLeft,
    ArrowRight,
    ArrowUp,
    BackSlash, // 反斜杠\
    Backspace, // 退格
    BackTick,
    BracketSquareLeft, // 左括号
    BracketSquareRight,
    CapsLock,   // 大写锁定
    Comma,  // 逗号
    ControlLeft, // 左ctrl
    ControlRight,
    Delete, // delete 键
    End, // 末尾
    Enter,
    Escape, // ESC键
    Equals, // 等号
    F1,
    F2,
    F3,
    F4,
    F5,
    F6,
    F7,
    F8,
    F9,
    F10,
    F11,
    F12,
    Fullstop, // 句号
    Home, // 首页
    Insert, // 插入
    Key1, // 大键盘 数字1
    Key2,
    Key3,
    Key4,
    Key5,
    Key6,
    Key7,
    Key8,
    Key9,
    Key0,
    Menus,
    Minus, // 减号
    Numpad0,
    Numpad1,
    Numpad2,
    Numpad3,
    Numpad4,
    Numpad5,
    Numpad6,
    Numpad7,
    Numpad8,
    Numpad9,
    NumpadEnter,
    NumpadLock,
    NumpadSlash,
    NumpadStar,
    NumpadMinus,
    NumpadPeriod,
    NumpadPlus,
    PageDown,
    PageUp,
    PauseBreak,
    PrintScreen,
    ScrollLock,
    SemiColon, // 分号
    ShiftLeft,
    ShiftRight,
    Slash, // 斜杠
    Spacebar,
    Tab,
    Quote,  // 引号
    WindowsLeft,
    WindowsRight,
    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
    J,
    K,
    L,
    M,
    N,
    O,
    P,
    Q,
    R,
    S,
    T,
    U,
    V,
    W,
    X,
    Y,
    Z,
    /// Not on US keyboards
    HashTilde,
    // Scan code set 1 unique codes
    PrevTrack,
    NextTrack,
    Mute,
    Calculator,
    Play,
    Stop,
    VolumeDown,
    VolumeUp,
    WWWHome,
    // Sent when the keyboard boots
    PowerOnTestOk,

    // 扩展前缀
    ExtendKeyPrefix,
}

pub struct ScanCodeSet1;
impl ScanCodeSet for ScanCodeSet1 {
    fn to_key(scancode: u8) -> Option<KeyEvent> {
        match scancode {
            // 主键盘上的字母
            0x1E => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::A }),
            0x30 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::B }),
            0x2E => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::C }),
            0x20 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::D }),
            0x12 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::E }),
            0x21 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::F }),
            0x22 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::G }),
            0x23 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::H }),
            0x17 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::I }),
            0x24 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::J }),
            0x25 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::K }),
            0x26 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::L }),
            0x32 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::M }),
            0x31 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::N }),
            0x18 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::O }),
            0x19 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::P }),
            0x10 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Q }),
            0x13 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::R }),
            0x1F => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::S }),
            0x14 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::T }),
            0x16 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::U }),
            0x2F => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::V }),
            0x11 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::W }),
            0x2D => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::X }),
            0x15 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Y }),
            0x2C => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Z }),

            // 主键盘上的数字、字符，通过shift键来显示数字或者字符
            0x02 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key1 }),
            0x03 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key2 }),
            0x04 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key3 }),
            0x05 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key4 }),
            0x06 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key5 }),
            0x07 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key6 }),
            0x08 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key7 }),
            0x09 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key8 }),
            0x0A => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key9 }),
            0x0B => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Key0 }),

            // 小键盘上的数字和字符
            0x52 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad0 }),
            0x4F => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad1 }),
            0x50 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad2 }),
            0x51 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad3 }),
            0x4B => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad4 }),
            0x4C => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad5 }),
            0x4D => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad6 }),
            0x47 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad7 }),
            0x48 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad8 }),
            0x49 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Numpad9 }),

            // SPACE
            0x39 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Spacebar }),

            // 主键盘Enter
            0x1C => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Enter }),
            0x9C => Some(KeyEvent { key_state: KeyState::KeyUp, key_code: KeyCode::Enter }),

            // 退格键
            0x0E => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Backspace }),

            // -和_
            0x0C => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Minus }),

            // =和+
            0x0D => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Equals }),

            // [和{
            0x1A => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::BracketSquareLeft }),

            // ]和}
            0x1B => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::BracketSquareRight }),

            // 反斜杠\和|
            0x2B => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::BackSlash }),

            // `和~
            0x29 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::BackTick }),

            // 斜杠/和?
            0x35 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Slash }),

            // 分号;和:
            0x27 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::SemiColon }),

            // 引号'和"
            0x28 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Quote }),

            // 逗号,和<
            0x33 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Comma }),

            // 句号.和>
            0x34 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::Fullstop }),

            // 左shift键的按下和弹起
            0x2A => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::ShiftLeft }),
            0xAA => Some(KeyEvent { key_state: KeyState::KeyUp, key_code: KeyCode::ShiftLeft }),
            // 右shift键的按下和弹起
            0x36 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::ShiftRight }),
            0xB6 => Some(KeyEvent { key_state: KeyState::KeyUp, key_code: KeyCode::ShiftRight }),

            // !TODO：键盘扩展扫描码，以0xE0开头的扫描码
            0xE0 => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::ExtendKeyPrefix }),
            
            // 扩展键盘上的Enter键
            // 0x1C => Some(KeyEvent { key_state: KeyState::KeyDown, key_code: KeyCode::NumpadEnter }),

            _ => { 
                None
            }
        }
    }
}

// 经过解码后的结果，保留解码后对应的键值和显示值
// 当前只做了ASCII码
pub struct KeyDecodeResult {
    key_code: KeyCode,
    key_disp: char,
}
pub trait KeyBoardLayout {
    fn decode(event: Option<KeyEvent>, ctrl: &mut ControlKey) -> Option<KeyDecodeResult>;
}

// 将按键事件和按键码转换成显示结果或动作
// 对应的自定义的处理动作
// 例如KeyCode::A转换成显示'A'或者'a'
// 例如KeyCode::Backspace要执行退格动作，KeyCode::Enter要执行换行动作
pub struct KeyBoardLayout1;
impl KeyBoardLayout1 {
    fn case_convert(ke: KeyEvent, ctrl_flag: bool, disp: char) -> Option<KeyDecodeResult> {
        if ctrl_flag { // 需要显示大写，传入的char是小写字母的ascii2码，大小要减去32
            Some(KeyDecodeResult { key_code: ke.key_code, key_disp: (disp as u8 - 32) as char })
        } else {
            Some(KeyDecodeResult { key_code: ke.key_code, key_disp: disp })
        }
    }

    fn num_or_sign_on_main_board(ke: KeyEvent, ctrl_flag: bool) -> Option<KeyDecodeResult> {
        let table = [('1', '!'), ('2', '@'), ('3', '#'), ('4', '$'), ('5', '%'), ('6', '^'), ('7', '&'), ('8', '*'), ('9', '('), ('0', ')')];
        let index = ke.key_code as u8 - KeyCode::Key1 as u8;
        if ctrl_flag { // shift选中，则显示数字上的符号
            Some(KeyDecodeResult { key_code: ke.key_code, key_disp: table[index as usize].1 })
        } else { // 否则显示数字
            Some(KeyDecodeResult { key_code: ke.key_code, key_disp: table[index as usize].0 })
        }
    }
}
impl KeyBoardLayout for KeyBoardLayout1 {
    fn decode(event: Option<KeyEvent>, ctrl: &mut ControlKey) -> Option<KeyDecodeResult> {
        match event {
            Some(e) => {
                match e.key_code {
                    KeyCode::A => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'a'),
                    KeyCode::B => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'b'),
                    KeyCode::C => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'c'),
                    KeyCode::D => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'd'),
                    KeyCode::E => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'e'),
                    KeyCode::F => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'f'),
                    KeyCode::G => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'g'),
                    KeyCode::H => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'h'),
                    KeyCode::I => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'i'),
                    KeyCode::J => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'j'),
                    KeyCode::K => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'k'),
                    KeyCode::L => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'l'),
                    KeyCode::M => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'm'),
                    KeyCode::N => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'n'),
                    KeyCode::O => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'o'),
                    KeyCode::P => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'p'),
                    KeyCode::Q => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'q'),
                    KeyCode::R => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'r'),
                    KeyCode::S => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 's'),
                    KeyCode::T => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 't'),
                    KeyCode::U => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'u'),
                    KeyCode::V => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'v'),
                    KeyCode::W => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'w'),
                    KeyCode::X => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'x'),
                    KeyCode::Y => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'y'),
                    KeyCode::Z => KeyBoardLayout1::case_convert(e, ctrl.lshift || ctrl.rshift, 'z'),

                    KeyCode::Key0 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key1 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key2 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key3 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key4 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key5 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key6 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key7 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key8 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),
                    KeyCode::Key9 => KeyBoardLayout1::num_or_sign_on_main_board(e, ctrl.lshift || ctrl.rshift),

                    KeyCode::Numpad0 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '0' }),
                    KeyCode::Numpad1 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '1' }),
                    KeyCode::Numpad2 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '2' }),
                    KeyCode::Numpad3 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '3' }),
                    KeyCode::Numpad4 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '4' }),
                    KeyCode::Numpad5 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '5' }),
                    KeyCode::Numpad6 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '6' }),
                    KeyCode::Numpad7 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '7' }),
                    KeyCode::Numpad8 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '8' }),
                    KeyCode::Numpad9 => Some(KeyDecodeResult { key_code: e.key_code, key_disp: '9' }),

                    KeyCode::Enter => { 
                        if e.key_state == KeyState::KeyUp {
                            ctrl.extend = false;
                            None
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '\n' })
                        } 
                    },

                    KeyCode::Spacebar => { Some(KeyDecodeResult { key_code: e.key_code, key_disp: ' ' }) },

                    KeyCode::Backspace => { Some(KeyDecodeResult { key_code: e.key_code, key_disp: 8 as char }) },

                    KeyCode::Minus => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '_' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '-' })
                        }
                    }

                    KeyCode::Equals => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '+' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '=' })
                        }
                    }

                    KeyCode::BracketSquareLeft => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '{' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '[' })
                        }
                    }

                    KeyCode::BracketSquareRight => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '}' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: ']' })
                        }
                    }

                    KeyCode::BackSlash => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '|' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '\\' })
                        }
                    }

                    KeyCode::Slash => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '?' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '/' })
                        }
                    }

                    KeyCode::SemiColon => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: ':' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: ';' })
                        }
                    }

                    KeyCode::Quote => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '"' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: 0x27 as char })
                        }
                    }

                    KeyCode::Comma => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '<' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: ',' })
                        }
                    }

                    KeyCode::Fullstop => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '>' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '.' })
                        }
                    }

                    KeyCode::BackTick => {
                        if ctrl.lshift || ctrl.rshift {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '~' })
                        } else {
                            Some(KeyDecodeResult { key_code: e.key_code, key_disp: '`' })
                        }
                    }

                    KeyCode::ShiftLeft => {
                        if e.key_state == KeyState::KeyDown {
                            ctrl.lshift = true;
                        } else {
                            ctrl.lshift = false;
                        }
                        None
                    },
                    KeyCode::ShiftRight => {
                        if e.key_state == KeyState::KeyDown {
                            ctrl.rshift = true;
                        } else {
                            ctrl.rshift = false;
                        }
                        None
                    },

                    KeyCode::ExtendKeyPrefix => {
                        // 扩展前缀0xE0
                        ctrl.extend = true;
                        None
                    }

                    _ => None
                }
            }
            _ => None
        }
    }
}

// 控制键的状态
pub struct ControlKey {
    lshift: bool,
    rshift: bool,
    lctrl: bool,
    rctrl: bool,
    caps_lock: bool,
    numlk: bool,
    extend: bool,
}

use core::marker::PhantomData;
struct KeyBoard<L, S> 
where
    L: KeyBoardLayout,
    S: ScanCodeSet,
{
    ctrl_key: ControlKey,
    _layout: PhantomData<L>,
    _scancodeset: PhantomData<S>,
}

impl<L, S>  KeyBoard<L, S> 
where
    L: KeyBoardLayout,
    S: ScanCodeSet,
{
    fn new(_layout: L, _scancodeset: S) -> KeyBoard<L, S> {
        KeyBoard {
            ctrl_key: ControlKey { lshift: false, rshift: false, lctrl: false, rctrl: false, caps_lock: false, numlk: false, extend: false },
            _layout: PhantomData,
            _scancodeset: PhantomData,
        }
    }

    pub fn translate(&mut self, scancode: u8) -> Option<KeyDecodeResult> {
        L::decode(S::to_key(scancode), &mut self.ctrl_key)
    }
}

fn g_translate(scancode: u8) -> Option<KeyDecodeResult> {
    static mut KEY_BOARD: Option<KeyBoard<KeyBoardLayout1, ScanCodeSet1>> = None;
    unsafe {
        match KEY_BOARD.as_mut() {
            Some(kb) => {
                return kb.translate(scancode);
            },
            None => {
                KEY_BOARD = Some(KeyBoard::new(KeyBoardLayout1, ScanCodeSet1));
                return KEY_BOARD.as_mut().unwrap().translate(scancode);
            }
        }
    }
}


#[no_mangle]
pub extern "C" fn keyboard_handler() {
    let scancode = ScanCode::read();
    //unsafe { printint(scancode as u32); print_char(' '); }
    if let Some(result) = g_translate(scancode) {
       unsafe { print_char(result.key_disp); }
    }
}